這篇文章將接續實作-商品系統(一)-設計概觀所提的想法,思考並設計出資料庫大概會是怎麼樣。
若要達成實作-商品系統(一)-設計概觀中的構想,等同於我們需要開一個新的database並新增三個table,分別是:
database: shopping_cart
member: 會員資料表,用來存放會員部分的資料。
product: 商品資料表,用來存放商品部分的資料。
order_list: 用來記錄哪位顧客在什麼時間買了什麼東西。
各個資料表生所生成的table欄位及欄位型態會是:
| id | name | password | img | img_name | create_date | update_date | |
|---|---|---|---|---|---|---|---|
| int(PK) | varchar | varchar | varchar | longblob | varchar | datetime | datetime | 
| id | name | price | quantity | img | img_name | remark | create_date | update_date | 
|---|---|---|---|---|---|---|---|---|
| int(PK) | varchar | decimal | int | longblob | varchar | varchar | datetime | datetime | 
| order_id | customer_id | product_id | order_quantity | order_price | is_complete | create_date | update_date | 
|---|---|---|---|---|---|---|---|
| int(PK) | int(PK, FK) | int(PK, FK) | int | decimal | int | datetime | datetime | 
這部分較為特別的是order_list的table會使用到來自member的id及product的id,而這兩個table的id值在order_list會被稱為是Foreign key(外來鍵)。且我們會額外將order_id, cusomter_id及product_id組合成Composite key(組合鍵)。

對不起,筆者寫字不漂亮,還用了不少立可白 Orz
上述的table若寫入資料後,會像下述這樣呈現。
假設目前有三個會員分別是cat, dog, penguin。
| id | name | password | img | img_name | create_date | update_date | |
|---|---|---|---|---|---|---|---|
| 1 | cat | test1@gmail.com | 1234 | [Base64..] | cat | 2018-01-01... | |
| 2 | dog | test2@gmail.com | 2345 | [Base64..] | dog | 2018-01-01... | |
| 3 | penguin | test3@gmail.com | 3456 | [Base64..] | penguin | 2018-01-01... | 
假設目前有三個商品分別是逗貓棒、潔牙骨跟企鵝玩偶。
| id | name | price | quantity | img | img_name | remark | create_date | update_date | 
|---|---|---|---|---|---|---|---|---|
| 1 | 逗貓棒 | 12.00 | 5 | [Base64..] | 逗貓棒 | 貓愛玩 | 2018-01-01... | |
| 2 | 潔牙骨 | 5.00 | 10 | [Base64..] | 潔牙骨 | 狗潔牙用 | 2018-01-01... | |
| 3 | 企鵝玩偶 | 20.00 | 3 | [Base64..] | 企鵝玩偶 | 鵝分身 | 2018-01-01... | 
假設會員cat他分別購買了三種商品,分別是:
| order_id | customer_id | product_id | order_quantity | order_price | is_complete | create_date | update_date | 
|---|---|---|---|---|---|---|---|
| 1 | 1 | 1 | 2 | 24.00 | 0 | 2018-01-05 | datetime | 
| 1 | 1 | 2 | 1 | 5.00 | 0 | 2018-01-05 | datetime | 
| 1 | 1 | 3 | 1 | 20.00 | 0 | 2018-01-05 | datetime | 
這部分的指令說明可參考關於後端觀念(七)-如何設定資料庫。
建立shopping_cart的資料庫:
mysql> CREATE DATABASE shopping_cart DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
Query OK, 1 row affected (0.00 sec)
之後給予我們先前設立的帳號使用shopping_cart資料庫的權限:
mysql> GRANT ALL PRIVILEGES ON shopping_cart.* TO 'testing'@'localhost';
Query OK, 0 rows affected (0.04 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
註記:
testing為展示用帳號,請自行更改成當初所設定的帳號。
之後,切換成testing的帳號,來編輯shopping_cart資料庫。
$ mysql -u testing -p
進入MySQL後,輸入use shopping_cart指令來切換資料庫。
mysql> use shopping_cart
mysql> CREATE TABLE member (
    -> id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    -> name VARCHAR(30) NOT NULL,
    -> email VARCHAR(30) NOT NULL,
    -> password VARCHAR(200) NOT NULL,
    -> img LONGBLOB,
    -> img_name VARCHAR(20),
    -> update_date DATETIME,
    -> create_date DATETIME NOT NULL);
Query OK, 0 rows affected (0.08 sec)
使用DESCRIBE member指令來觀看整個table的data type:
mysql> DESCRIBE member;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| name        | varchar(30)  | NO   |     | NULL    |                |
| email       | varchar(30)  | NO   |     | NULL    |                |
| password    | varchar(200) | NO   |     | NULL    |                |
| img         | longblob     | YES  |     | NULL    |                |
| img_name    | varchar(20)  | YES  |     | NULL    |                |
| update_date | datetime     | YES  |     | NULL    |                |
| create_date | datetime     | NO   |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
8 rows in set (0.03 sec)
mysql> CREATE TABLE product (
    -> id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    -> name VARCHAR(30) NOT NULL,
    -> price DECIMAL(5,2) NOT NULL,
    -> quantity INT(10) NOT NULL,
    -> img LONGBLOB,
    -> img_name VARCHAR(20),
    -> remark VARCHAR(100),
    -> update_date DATETIME,
    -> create_date DATETIME NOT NULL);
Query OK, 0 rows affected (0.05 sec)
使用DESCRIBE product指令來觀看整個table的data type:
mysql> DESCRIBE product;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| name        | varchar(30)  | NO   |     | NULL    |                |
| price       | decimal(5,2) | NO   |     | NULL    |                |
| quantity    | int(10)      | NO   |     | NULL    |                |
| img         | longblob     | YES  |     | NULL    |                |
| img_name    | varchar(20)  | YES  |     | NULL    |                |
| remark      | varchar(100) | YES  |     | NULL    |                |
| update_date | datetime     | YES  |     | NULL    |                |
| create_date | datetime     | NO   |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
9 rows in set (0.01 sec)
mysql> CREATE TABLE order_list (
    -> order_id INT NOT NULL,
    -> member_id INT NOT NULL,
    -> product_id INT NOT NULL,
    -> order_quantity INT(10) NOT NULL,
    -> order_price DECIMAL(10,2) NOT NULL,
    -> is_complete INT(5) NOT NULL,
    -> update_date DATETIME,
    -> order_date DATETIME NOT NULL,
    -> PRIMARY KEY(order_id, member_id, product_id),
    -> FOREIGN KEY (member_id) REFERENCES member (id),
    -> FOREIGN KEY (product_id) REFERENCES product (id));
Query OK, 0 rows affected (0.03 sec)
使用DESCRIBE order_list指令來觀看整個table的data type:
mysql> DESCRIBE order_list;
+----------------+---------------+------+-----+---------+-------+
| Field          | Type          | Null | Key | Default | Extra |
+----------------+---------------+------+-----+---------+-------+
| order_id       | int(11)       | NO   | PRI | NULL    |       |
| member_id      | int(11)       | NO   | PRI | NULL    |       |
| product_id     | int(11)       | NO   | PRI | NULL    |       |
| order_quantity | int(10)       | NO   |     | NULL    |       |
| order_price    | decimal(10,2) | NO   |     | NULL    |       |
| is_complete    | int(5)        | NO   |     | NULL    |       |
| update_date    | datetime      | YES  |     | NULL    |       |
| order_date     | datetime      | NO   |     | NULL    |       |
+----------------+---------------+------+-----+---------+-------+
8 rows in set (0.01 sec)
該部分較為特別的是我們有額外用到Foreign key(外來鍵)及Composite key(組合鍵),且其order_list table的設計方式也不只有筆者的這種設計方式,讀者也可以試著去修改看看想要呈現的方式。在下篇我們就接續進入到寫程式的階段。